﻿//-----------------------------------------------------------------------------------------------------------
// WBFSSync Project by Omega Frost 
// http://wbfssync.codeplex.com/
//
// WBFSSync is Licensed under the terms of the 
// Microsoft Reciprocal License (Ms-RL)
//-----------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using WBFSe3.Wbfs;
using WBFSe3.Streams;
using WBFSe3.IO;
using WBFSe3.Interfaces;

namespace WBFSe3.Formats
{
    //-------------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------------
    public class WbfsPWbfsReader : WbfsFormatReader
    {
        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        WbfsDevice device;
        int discIdx;
        ushort[] sectorTable;


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public override WbfsError Initialize(WbfsDriveInfo drive, WbfsPath directory, string file)
        {
            WbfsError error;

            this.version = 1;

            // Get the device and the sector size
            this.device = (WbfsDevice)drive;
            this.sectorSize = this.device.WbfsSectorSize;

            // Split the discidx from the filename
            this.discIdx = this.device.GetDiscIndex(file);

            // Build the path
            this.path = new WbfsPath(drive.Name, new 
                String[] { file });

            // Load the sector table

            error = this.device.GetDiscSectorTable(out 
                this.sectorTable, this.discIdx);
            if (error != WbfsError.Ok) return error;

            // Calculate sizes
            this.fileSize = 0;
            this.fileLength = this.sectorTable.Length * this.sectorSize;
            
            for (int i = 0; i < this.sectorTable.Length; i++)
            {
                if (this.sectorTable[i] != 0)
                    this.fileSize++;
            }

            this.fileSize *= this.sectorSize;
            return WbfsError.Ok;
        }


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public override WbfsError Fix()
        {
            // Sorry... no way... for now
            return WbfsError.FormatBadFile;
        }


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public override WbfsError ChangeHeader(string name, string code, WbfsRegion region)
        {
            WbfsError error;
            Byte[] header;
            error = this.device.GetDiscHeaderCopy(out header, this.discIdx);
            if (error != WbfsError.Ok) return error;

            byte[] bcode = new byte[WbfsConstants.WiiCodeLen];
            byte[] bname = new byte[WbfsConstants.WiiNameLen];

            Encoding.Default.GetBytes(code).CopyTo(bcode, 0);
            Encoding.Default.GetBytes(name).CopyTo(bname, 0);

            bcode.CopyTo(header, WbfsConstants.WiiCodePos);
            bname.CopyTo(header, WbfsConstants.WiiNamePos);

            return this.device.SetDiscHeaderCopy(header, this.discIdx);
        }


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        protected override WbfsError EmmitStream(FileAccess access, FileShare share, out WbfsStream stream)
        {
            WbfsDeviceStream d = new WbfsDeviceStream(this.path[0], this.sectorSize, FileAccess.ReadWrite);
            stream = new WbfsSectorStream(d, this.sectorSize, this.sectorTable);
            return WbfsError.Ok;
        }


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public override void Close()
        {
            // Do nothing...
        }
    }
}
